package controllers

import (
	"encoding/json"
	"fmt"
	ck_orm "github.com/clakeboy/ck-orm"
	"github.com/clakeboy/golib/utils"
	"github.com/gin-gonic/gin"
)

const (
	EQ   = "eq"
	NE   = "ne"
	GT   = "gt"
	GTE  = "gte"
	LT   = "lt"
	LTE  = "lte"
	LIKE = "like"
)

var ConditionSymbol = utils.M{
	"eq":   "=",
	"ne":   "!=",
	"gt":   ">",
	"gte":  ">=",
	"lt":   "<",
	"lte":  "<=",
	"like": "like",
}

type DataParams struct {
	TableName  string            `json:"table_name"`
	Page       int               `json:"page"`
	Number     int               `json:"number"`
	Orders     []*OrderParam     `json:"orders"`
	Conditions []*ConditionParam `json:"conditions"`
}

//条件参数
type ConditionParam struct {
	Field string `json:"field"`
	Value string `json:"value"`
	Flag  string `json:"flag"`
}

//排序参数
type OrderParam struct {
	Field string `json:"field"`
	Type  string `json:"type"`
}

type DefaultController struct {
	c *gin.Context
}

func NewDefaultController(c *gin.Context) *DefaultController {
	return &DefaultController{c: c}
}

func (d *DefaultController) ActionGetData(args []byte) (interface{}, error) {
	params := &DataParams{}
	err := json.Unmarshal(args, params)
	if err != nil {
		return nil, err
	}
	db := d.c.MustGet("sqlite").(*ck_orm.DBA)
	tab := db.Table(params.TableName)
	where := explainCondition(params.Conditions)
	if len(where) > 0 {
		tab.Where(where, "")
	}
	order := explainOrder(params.Orders)
	if len(order) > 0 {
		tab.Order(order)
	}
	dataCount := tab.Rows()
	res, err := tab.Limit(params.Number, params.Page).Query().Result()
	if err != nil {
		return nil, err
	}

	return utils.M{
		"list":  res,
		"count": dataCount,
	}, nil
}

func explainCondition(conditions []*ConditionParam) utils.M {
	where := utils.M{}
	for _, v := range conditions {
		switch v.Flag {
		case EQ:
			where[v.Field] = v.Value
		default:
			where[fmt.Sprintf("%s[%s]", v.Field, ConditionSymbol[v.Flag])] = v.Value
		}
	}

	return where
}

func explainOrder(orderList []*OrderParam) utils.M {
	order := utils.M{}
	for _, v := range orderList {
		order[v.Field] = v.Type
	}
	return order
}
